package myservice.android.utilities;

import myservice.android.Global;
import myservice.android.R;
import myservice.android.database.Database;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class GraphCanvas extends View {
	
	// Contains data for one month
	private class MonthRecord {
		int month, year;
		int ministryHours, creditHours;
		int magazines, books, brochures, tracts, videos, returnCalls, bibleStudents;
	}
	
	final int bottomMargin = 20; // number of pixels reserved under the graph for month names
	final int leftMargin = 40; // number of pixels reserved on the left side for numbers
	final int rightMargin = 20; // margin on the right side in pixels
	final int topMargin = 10; // margin on the top	
		
	private Paint paint;	
	
	private String[] monthNames;
	private MonthRecord[] monthRecord;	
	
	private int maxWidth, maxHeight;
	private int monthCount;
	private int largestNumber; // stores the largest number (time, magazines, etc.) across all months for vertical scaling
	private boolean anyDataPresent;
	
	public GraphCanvas(Context context) {
		super(context);			
		init();
	}		
	
	public GraphCanvas(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public GraphCanvas(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}
	
	private void init() {
		
		monthNames=Global.res.getStringArray(R.array.array_month_names_short);		
		
		paint = new Paint();
		
		paint.setDither(true);
		paint.setStyle(Paint.Style.FILL);
		paint.setStrokeWidth(1);
		paint.setTextSize(12);
	}
	
	@Override
	public void onDraw(Canvas canvas) {	
		
		// Available size of the screen
		maxWidth = getMeasuredWidth()-1;
		maxHeight = getMeasuredHeight()-1;
		
		monthCount = (Global.toYear*12+Global.toMonth) - (Global.fromYear*12+Global.fromMonth) + 1;
		
		anyDataPresent = true;
		largestNumber = 0;
		
		collectData();
		
		if (largestNumber==0) {
			largestNumber=1;
			anyDataPresent=false;
		}
		
		int horizontalRatio = (maxWidth-leftMargin-rightMargin) / (monthCount-1);
		int verticalRatio = (maxHeight-bottomMargin-topMargin) / largestNumber;
		
		// Draw graph axis
		paint.setColor(0xFF444444);
		canvas.drawLine(leftMargin, topMargin, leftMargin, maxHeight-bottomMargin, paint);		
		canvas.drawLine(leftMargin, maxHeight-bottomMargin, maxWidth-rightMargin, maxHeight-bottomMargin, paint);	
		
		// Draw month names
		paint.setTextAlign(Paint.Align.CENTER);
		int averageLabelWidth;
		if (Global.fromYear!=Global.toYear)
			averageLabelWidth = Math.round(paint.measureText("Oct 2013"))+20;
		else
			averageLabelWidth = Math.round(paint.measureText("Oct"))+20;
		int maxMonthLabels = ((maxWidth-leftMargin-rightMargin) / averageLabelWidth) - 1;
		int labelFrequency; 		
		if (maxMonthLabels>=monthCount)
			labelFrequency = 1;
		else
			labelFrequency=monthCount/maxMonthLabels;		
		
		int f = labelFrequency;
		
		for (int i=0; i<monthCount; i++) {
			f++;
			if (f>=labelFrequency) {
				paint.setColor(0xFFFFFFFF);
				if (Global.fromYear!=Global.toYear)				
					canvas.drawText(monthNames[monthRecord[i].month]+" "+monthRecord[i].year, leftMargin+i*horizontalRatio, maxHeight-4, paint);
				else
					canvas.drawText(monthNames[monthRecord[i].month], leftMargin+i*horizontalRatio, maxHeight-4, paint);
				paint.setColor(0xFF444444);
				canvas.drawLine(leftMargin+i*horizontalRatio, maxHeight-bottomMargin-3, leftMargin+i*horizontalRatio, maxHeight-bottomMargin+3, paint);
				f=0;
			}
		}
		
		if (anyDataPresent==true) {
			// Draw numbers on the vertical axis
			paint.setTextAlign(Paint.Align.RIGHT);
			int averageLabelHeight = 20;
			int maxLabels = ((maxHeight-bottomMargin-topMargin) / averageLabelHeight) - 1;
			if (maxLabels>10)
				maxLabels=10;
			if (maxLabels>=largestNumber)
				labelFrequency = 1;
			else
				labelFrequency=largestNumber/maxLabels;		
		
			f = 0;
		
			for (int i=1; i<=largestNumber; i++) {
				f++;
				if (f>=labelFrequency) {
					paint.setColor(0xFFFFFFFF);
					canvas.drawText(""+i, leftMargin-5, maxHeight-bottomMargin-i*verticalRatio+5, paint);
					paint.setColor(0xFF444444);
					canvas.drawLine(leftMargin-3,maxHeight-bottomMargin-i*verticalRatio, leftMargin+3, maxHeight-bottomMargin-i*verticalRatio, paint);
					f=0;
				}
			}
		}
		
		paint.setStrokeWidth(2);
		
		// Draw Bible students graph
		if (Global.showBibleStudentsGraph==true) {
			paint.setColor(0xFFFF0000);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].bibleStudents*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].bibleStudents*verticalRatio, paint);
			}
		}			
		
		// Draw brochures graph
		if (Global.showBrochuresGraph==true) {
			paint.setColor(0xFFA349A4);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].brochures*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].brochures*verticalRatio, paint);
			}
		}
		
		// Draw tracts graph
		if (Global.showTractsGraph==true) {
			paint.setColor(0xFFC3C3C3);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].tracts*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].tracts*verticalRatio, paint);
			}
		}	
		
		// Draw videos graph
		if (Global.showVideosGraph==true) {
			paint.setColor(0xFFC8BFE7);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].videos*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].videos*verticalRatio, paint);
			}
		}			
		
		// Draw books graph
		if (Global.showBooksGraph==true) {
			paint.setColor(0xFF22B14C);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].books*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].books*verticalRatio, paint);
			}
		}
		
		// Draw return calls graph
		if (Global.showReturnCallsGraph==true) {
			paint.setColor(0xFFB97A57);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].returnCalls*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].returnCalls*verticalRatio, paint);
			}
		}		
		
		// Draw magazines graph
		if (Global.showMagazinesGraph==true) {
			paint.setColor(0xFF00A2E8);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].magazines*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].magazines*verticalRatio, paint);
			}
		}		
		
		// Draw total time graph
		if (Global.showTotalTimeGraph==true) {
			paint.setColor(0XFFFFFF00);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-(monthRecord[i-1].ministryHours+monthRecord[i-1].creditHours)*verticalRatio,
						        leftMargin+i*horizontalRatio, maxHeight-bottomMargin-(monthRecord[i].ministryHours+monthRecord[i].creditHours)*verticalRatio, paint);
			}
		}
		
		// Draw credit time graph
		if (Global.showCreditTimeGraph==true) {
			paint.setColor(0xFF3F48CC);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].creditHours*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].creditHours*verticalRatio, paint);
			}
		}		
		
		// Draw ministry time graph
		if (Global.showMinistryTimeGraph==true) {
			paint.setColor(0xFFFF7F27);
			for (int i=1; i<monthCount; i++) {		
				canvas.drawLine(leftMargin+(i-1)*horizontalRatio, maxHeight-bottomMargin-monthRecord[i-1].ministryHours*verticalRatio, leftMargin+i*horizontalRatio,
						        maxHeight-bottomMargin-monthRecord[i].ministryHours*verticalRatio, paint);
			}
		}				
		
		paint.setStrokeWidth(1);
		
	}
	
	// Collect data for every month in the selected range
	private void collectData() {
		
		monthRecord = new MonthRecord[monthCount];
		
		int month = Global.fromMonth;
		int year = Global.fromYear;
		
		for (int i=0; i<monthCount; i++) {	
			
			monthRecord[i] = new MonthRecord();
			monthRecord[i].month=month;
			monthRecord[i].year=year;
			
			Cursor cursor = Database.select("SELECT SUM(hours) AS h, SUM(minutes) AS m, SUM(chours) AS ch, SUM(cminutes) AS cm, SUM(magazines) AS mg, SUM(books) AS bk, "+
			                                "SUM(brochures) AS br, SUM(tracts) AS tr, SUM(videos) AS vi, SUM(returncalls) AS rc FROM ministry WHERE month="+month+" AND year="+year);
			cursor.moveToNext();
			
			int h = cursor.getInt(cursor.getColumnIndex("h"));
			int m = cursor.getInt(cursor.getColumnIndex("m"));
			int ch = cursor.getInt(cursor.getColumnIndex("ch"));
			int cm = cursor.getInt(cursor.getColumnIndex("cm"));
			
			monthRecord[i].ministryHours=(h*60 + m) / 60;			
			monthRecord[i].creditHours=(ch*60 + cm) / 60;
			
			if (Global.showTotalTimeGraph==true && (monthRecord[i].ministryHours+monthRecord[i].creditHours)>largestNumber)
				largestNumber=monthRecord[i].ministryHours+monthRecord[i].creditHours;
			else {
				if (Global.showMinistryTimeGraph==true && monthRecord[i].ministryHours>largestNumber)
					largestNumber=monthRecord[i].ministryHours;
				if (Global.showCreditTimeGraph==true && monthRecord[i].creditHours>largestNumber)
					largestNumber=monthRecord[i].creditHours;				
			}
			
			monthRecord[i].magazines=cursor.getInt(cursor.getColumnIndex("mg"));
			if (Global.showMagazinesGraph==true && monthRecord[i].magazines>largestNumber)
				largestNumber=monthRecord[i].magazines;		
			
			monthRecord[i].books=cursor.getInt(cursor.getColumnIndex("bk"));
			if (Global.showBooksGraph==true && monthRecord[i].books>largestNumber)
				largestNumber=monthRecord[i].books;
			
			monthRecord[i].brochures=cursor.getInt(cursor.getColumnIndex("br"));
			if (Global.showBrochuresGraph==true && monthRecord[i].brochures>largestNumber)
				largestNumber=monthRecord[i].brochures;
			
			monthRecord[i].tracts=cursor.getInt(cursor.getColumnIndex("tr"));
			if (Global.showTractsGraph==true && monthRecord[i].tracts>largestNumber)
				largestNumber=monthRecord[i].tracts;	
			
			monthRecord[i].videos=cursor.getInt(cursor.getColumnIndex("vi"));
			if (Global.showVideosGraph==true && monthRecord[i].videos>largestNumber)
				largestNumber=monthRecord[i].videos;			
			
			monthRecord[i].returnCalls=cursor.getInt(cursor.getColumnIndex("rc"));
			if (Global.showReturnCallsGraph==true && monthRecord[i].returnCalls>largestNumber)
				largestNumber=monthRecord[i].returnCalls;				
			
			cursor.close();
			
			// calculate individual Bible students (status=Bible student, and at least one call marked as Bible study was conducted in that month)
			cursor = Database.select("SELECT DISTINCT name FROM persons JOIN calls ON persons.personid=calls.personid WHERE status=3 AND biblestudy=1 AND month="+month+
					                 " AND year="+year+" AND persons.timestamp<>"+Global.TIMESTAMP_DELETED);
			monthRecord[i].bibleStudents=cursor.getCount();
			if (Global.showBibleStudentsGraph==true && monthRecord[i].bibleStudents>largestNumber)
				largestNumber=monthRecord[i].bibleStudents;			
			cursor.close();			
			
			month++;
			if (month>11) {
				month=0; year++;
			}
			
		}
		
	}

}
